home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / wb2argv.lha / WB2Argv.c < prev    next >
C/C++ Source or Header  |  1996-02-10  |  6KB  |  276 lines

  1. /*
  2.  *  WB2Argv v1.0, Amiga Workbench argv/argc emulation routines.
  3.  *  Copyright (C) 1995-96 Jens T. Berger Thielemann
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  Contact the author at:
  20.  *        Jens Berger
  21.  *        Spektrumvn. 4
  22.  *        N-0666 Oslo
  23.  *        Norway
  24.  *        E-mail: <jensthi@ifi.uio.no>
  25.  *
  26.  *  Note: If you use any of these routines in your programs, you have to
  27.  *  mention so in the document.
  28.  *
  29.  *
  30.  */
  31.  
  32. #ifdef AMIGA
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38.  
  39. #include <workbench/startup.h>
  40. #include <proto/dos.h>
  41. #include <workbench/workbench.h>
  42. #include <proto/icon.h>
  43. #include <proto/exec.h>
  44.  
  45. #include "WB2Argv.h"
  46.  
  47. /* #define WB_DEBUG */
  48.  
  49. #ifdef WB_DEBUG
  50. char __stdiowin[] = "CON:0/10/640/180/WB2Argv";
  51. char __stdiov37[] = "/AUTO/CLOSE/WAIT";
  52. #endif
  53.  
  54. /*
  55.  * Concatenates the `File' string to the `Dir' string, leaving the result
  56.  * in the `Dir' buffer. Takes care of inserting `directory' characters;
  57.  * if we've got the strings "/usr/foo" and "bar", we'll get
  58.  * "/usr/foo/bar".
  59.  *
  60.  * Behaviour somewhat controlled by the macros SLASH and DIRCHARS in the
  61.  * .h file.
  62.  *
  63.  */
  64.  
  65. #define DIRCHARS ":/"
  66. #define SLASH '/'
  67.  
  68. void tackon(STRPTR Dir, const STRPTR File)
  69. {
  70.     UBYTE    EndC;
  71.     ULONG    SLen;
  72.  
  73.     if(Dir && (SLen = strlen(Dir)))
  74.     {
  75.         EndC = Dir[SLen -1];
  76.         if(!strchr(DIRCHARS, EndC))
  77.         {
  78.             Dir[SLen++] = SLASH;
  79.             Dir[SLen  ] = 0;
  80.         }
  81.     }
  82.  
  83.     strcat(Dir, File);
  84. }
  85.  
  86.  
  87.  
  88. /*
  89.  * Converts a message from workbench into an argv look-a-like. Tooltypes
  90.  * are converted to long-named options, suitable for passing to GNU's
  91.  * getopt_long(). Shift-clicked files will be appended at the end; their
  92.  * tooltypes will _currently_ not be processed. This may happen in a future
  93.  * version (is it desirable?).
  94.  *
  95.  * Flags: Currently these do only control whether we'll convert the
  96.  * case of the options. See WB2Argv.h for options.
  97.  *
  98.  * Returns an array of string-pointers; terminated with a NULL. To get
  99.  * argc, call CountArgv().
  100.  */
  101.  
  102.  
  103. char **WB2Argv(struct WBStartup *WBMsg, LONGBITS Flags)
  104. {
  105.     ULONG    c = 0,
  106.             CurArg = 0,
  107.             NewArgc = 0;
  108.     STRPTR    *NewArgv,
  109.             *Tools,
  110.             Buf;
  111.     BPTR    OldCurDir;
  112.     BOOL    TmpSucc = TRUE,
  113.             IconOpen = FALSE;
  114.     struct DiskObject *dskobj = NULL;
  115.  
  116.     if(WBMsg && (DOSBase->dl_lib.lib_Version > 36))
  117.     {
  118.         OldCurDir = CurrentDir(WBMsg->sm_ArgList->wa_Lock);
  119.  
  120.         /*
  121.          * First, count the # of argv entries. We get both from
  122.          * shift-clicked icons + tooltypes.
  123.          */
  124.  
  125.         NewArgc = WBMsg->sm_NumArgs;
  126.  
  127.          if(IconBase = OpenLibrary("icon.library", 0))
  128.         {
  129.             IconOpen = TRUE;
  130.             if(dskobj = GetDiskObject(WBMsg->sm_ArgList->wa_Name))
  131.             {
  132.                 Tools = dskobj->do_ToolTypes;
  133.  
  134.                 while(*Tools++)
  135.                     NewArgc++;
  136.             }
  137.         }
  138.  
  139.         /*
  140.          * Stuff it together...
  141.          */
  142.  
  143.         if(NewArgv = calloc(NewArgc + 2, sizeof(APTR)))
  144.         {
  145.             CurArg = 0;
  146.  
  147.             /* Program name */
  148.  
  149.             if(Buf = malloc(sizeof(UBYTE) * BUFSIZ))
  150.             {
  151.                 CurrentDir(WBMsg->sm_ArgList->wa_Lock);
  152.  
  153.                 if(NameFromLock(WBMsg->sm_ArgList->wa_Lock, Buf, BUFSIZ))
  154.                 {
  155.                     tackon(Buf, WBMsg->sm_ArgList->wa_Name);
  156.                     NewArgv[CurArg++] = Buf;
  157.                 }
  158.             }
  159.  
  160.             if(dskobj)
  161.             {
  162.                 /* Tooltypes becomes longnamed options */
  163.                 for(Tools = dskobj->do_ToolTypes;
  164.                     *Tools && TmpSucc;
  165.                     Tools++)
  166.                 {
  167.                     /* To avoid a false `--' */
  168.                     if(**Tools)
  169.                     {
  170.                         TmpSucc = FALSE;
  171.  
  172.                         if(Buf = malloc(strlen(*Tools) + 4))
  173.                         {
  174.                             strcpy(Buf, "--");
  175.                             strcat(Buf, *Tools);
  176.  
  177.                             TmpSucc = TRUE;
  178.                             NewArgv[CurArg++] = Buf;
  179.  
  180.                             /* Make option lowercase */
  181.  
  182.                             switch(Flags & W2A_CASEMASK)
  183.                             {
  184.                             case W2A_LOWER:
  185.                                 for(;
  186.                                     *Buf && (*Buf != '=');
  187.                                     Buf++)
  188.                                     *Buf = tolower(*Buf);
  189.                                 break;
  190.                             case W2A_UPPER:
  191.                                 for(;
  192.                                     *Buf && (*Buf != '=');
  193.                                     Buf++)
  194.                                     *Buf = toupper(*Buf);
  195.                                 break;
  196.                             case W2A_KEEPCASE:
  197.                                 break;
  198.                             }
  199.                         }
  200.                     }
  201.                 }
  202.             }
  203.  
  204.             /* End of options... */
  205.             NewArgv[CurArg++] = "--";
  206.  
  207.             if(TmpSucc)
  208.             {
  209.                 for(c = 1;            /* Skip program name */
  210.                    (c < WBMsg->sm_NumArgs) && TmpSucc;
  211.                     c++)
  212.                 {
  213.                     TmpSucc = FALSE;
  214.                     if(Buf = malloc(sizeof(UBYTE) * BUFSIZ))
  215.                     {
  216.                         CurrentDir(WBMsg->sm_ArgList[c].wa_Lock);
  217.  
  218.                         if(NameFromLock(WBMsg->sm_ArgList[c].wa_Lock, Buf, BUFSIZ))
  219.                         {
  220.                             tackon(Buf, WBMsg->sm_ArgList[c].wa_Name);
  221.                             NewArgv[CurArg++] = Buf;
  222.                             TmpSucc = TRUE;
  223.                         }
  224.                     }
  225.                 }
  226.             }
  227.         }
  228.         CurrentDir(OldCurDir);
  229.  
  230.         if(dskobj)
  231.             FreeDiskObject(dskobj);
  232.  
  233.         if(IconOpen)
  234.             CloseLibrary(IconBase);
  235.  
  236.         if(TmpSucc)
  237.             return(NewArgv);
  238.     }
  239.  
  240.     return(NULL);
  241. }
  242.  
  243. ULONG CountArgv(const char **argv)
  244. {
  245.     ULONG argc = 0;
  246.  
  247.     if(argv)
  248.     {
  249.         while(*argv++)
  250.             argc++;
  251.     }
  252.     return(argc);
  253. }
  254.  
  255. #ifdef WB_DEBUG
  256. #    define EXIT_FAILURE    20
  257. void main(int argc, char **argv)
  258. {
  259.     int c;
  260.     if(_WBenchMsg)
  261.     {
  262.         if(argv = WB2Argv(_WBenchMsg, W2A_LOWER))
  263.             argc = CountArgv(argv);
  264.         else
  265.             exit(EXIT_FAILURE);
  266.     }
  267.  
  268.     for(c = 0; c < argc; c++)
  269.         printf("%s\n", argv[c]);
  270.  
  271. }
  272.  
  273. #endif /* WB_DEBUG */
  274.  
  275. #endif /* AMIGA */
  276.